<script setup>
import request from '@/utils/request'
import { computed, onMounted, reactive, ref, watch } from 'vue'

const props = defineProps({
  modelValue: {
    type: Array,
    default: () => []
  },
  data: {
    type: Array,
    required: false
  },
  url: {
    type: String,
    required: false
  },
  dataFunction: {
    type: Function,
    required: false
  },
  formatFunction: {
    type: Function,
    default: item => item
  },
  keyField: {
    type: String,
    default: 'id'
  },
  labelField: {
    type: String,
    default: 'name'
  },
  valueField: {
    type: String,
    default: 'value'
  },
  placeholder: {
    type: String,
    default: '请选择'
  },
  style: {
    type: String,
    default: 'width: 160px'
  }
})

const emit = defineEmits(['update:modelValue'])

const model = computed({
  get() {
    return props.modelValue
  },
  set(val) {
    emit('update:modelValue', val)
  }
})

const list = ref([])

const state = reactive({
  all: false,
  invert: false
})

onMounted(async () => {
  if (props.data) {
    list.value = props.data
  } else if (props.dataFunction) {
    list.value = props.formatFunction(await props.dataFunction())
  } else if (props.url) {
    request.get(props.url).then(res => {
      list.value = props.formatFunction(res)
    })
  }
})
watch(() => props.data, () => {
  list.value = props.data
})

watch(() => state.all, val => {
  if (val) {
    model.value = list.value.map(item => item[props.valueField])
  } else {
    model.value = []
  }
})

watch(() => state.invert, val => {
  if (val) {
    model.value = list.value.map(item => item[props.valueField]).filter(item => !model.value.includes(item))
  }
})

function handleChange() {

}
</script>

<template>
  <el-select
    v-model="model"
    :placeholder="placeholder"
    :style="style"
    size="small"
    multiple
    clearable
    collapse-tags
    collapse-tags-tooltip
    @change="handleChange"
  >
    <el-option value="" style="padding-left: 20px" disabled>
      <el-checkbox v-model="state.all">全选</el-checkbox>
      <el-checkbox v-model="state.invert">反选</el-checkbox>
    </el-option>
    <el-option
      v-for="item in list" :key="item[keyField]" :label="item[labelField]" :value="item[valueField]"
    />
  </el-select>
</template>
